import React, { PureComponent } from 'react'
import { connect, history } from '@umijs/max'
import {
  Button, Checkbox, Form, Input, message, Radio, Select, TreeSelect, Switch,
} from 'antd'
import lodash from 'lodash'
import list2tree from 'list2tree'
import { BreadcrumbBar, ProTable } from '@/components'
import { TestModal } from './page-components'
import styles from './index.less'
import {
  requestIdMap, responseIdMap, returnDescId, returnMenuList,
} from '@/utils/utils'
import { getHashParameterByName } from '@/utils/helper'
import {
  paramDataTypeArr, descRe, pathRe, lenRe, txtRe,
} from '@/utils/constans'
import {
  selectedApiTypeToColumn,
} from '@/customLibrary/api-create'

const { cloneDeep } = lodash
const { Item } = Form
const { TextArea } = Input
const { Option } = Select
const descId = returnDescId()
const menuList = returnMenuList(descId)

// 请求参数中的参数类型
const getNavTreeDataFunc = list2tree({
  idKey: 'id',
  parentIdKey: 'pid',
  newKey: {
    key: 'id',
    value: 'id',
    title: 'name',
  },
})

const getNavTreeDataFunc2 = list2tree({
  idKey: 'id',
  parentIdKey: 'pid',
  newKey: {
    key: 'id',
    value: 'id',
    title: 'dirName',
  },
})

@connect(({ indexApiCreate }) => ({ ...indexApiCreate }))
class ProduceApiCreate extends PureComponent {
  selectedApiTypeToColumn = selectedApiTypeToColumn.call(this, 'notDelete')

  constructor(props) {
    super(props)
    this.state = {
      // selectedApiType: '1', // 同脚本模式
      indexNameList: [], // 指标名称列表
      fieldDataSource: [], // 参数选择 数据源
      fieldLoading: false,
      requestParams: [], // 请求参数设置 数据源
      responseParams: [], // 返回参数设置 数据源
      pageable: 0,
    }
    this.dataSourceForm = React.createRef()
    this.testModalRef = React.createRef()
  }

  componentDidMount() {
    this.queryListCatalog()
    this.queryGetApiGroup()
    this.descId = getHashParameterByName('id') || ''
    this.descId && this.viewDetail(this.descId)
    const dirKey = getHashParameterByName('dirKey') || ''
    if (dirKey) {
      this.dataSourceForm.current?.setFieldsValue({ apiGroupId: dirKey })
    }
  }

  // 查看详情
  viewDetail = (id) => {
    this.props.dispatch({
      type: 'indexApiCreate/queryGetDataApiDetailById',
      params: { id },
      cb: (res) => {
        const { status, msg, data = {} } = res || {}
        if (status === 200) {
          const {
            apiType,
            apiName,
            apiPath,
            apiProtocol,
            apiMethod,
            authType,
            apiGroupId,
            apiDesc,
            datasourceId,
            tableName,
            pageable,
            inputParamResponses,
            outputParamResponses,
            dirId,
            indexId,
            isSecurity,
          } = data

          this.dataSourceForm.current?.setFieldsValue({
            apiType,
            apiName,
            apiPath,
            apiProtocol,
            apiMethod,
            apiGroupId,
            apiDesc,
            datasourceId,
            tableName,
            dirId,
            indexId,
            authType: authType ? 1 : 0,
            isSecurity: !!isSecurity,
          })

          this.queryGetPublishedIndex(dirId, indexId)

          this.setState({
            // selectedDataSource: datasourceId,
            pageable,
            requestParams: inputParamResponses.map(requestIdMap),
            responseParams: outputParamResponses.map(responseIdMap),
          }, () => {
            // this.handleSelectTableName(tableName)
            // this.queryGetTableInfoList(datasourceId)
          })
        } else {
          message.error(msg || '服务端错误')
        }
      },
    })
  }

  // 获取指标目录
  queryListCatalog = () => {
    this.props.dispatch({
      type: 'indexApiCreate/queryListCatalog',
      params: {},
      cb: (res) => {
        this.setState({
          treeData: getNavTreeDataFunc(res || []),
        })
      },
    })
  }

  // 获取API分组
  queryGetApiGroup = () => {
    this.props.dispatch({
      type: 'indexApiCreate/queryGetApiGroup',
      params: {},
      cb: (res) => {
        this.setState({
          // apiGroupList: res || [],
          apiGroupList: getNavTreeDataFunc2(res || []),
        })
      },
    })
  }

  // 参数选择 - 设为请求参数 - checkbox选择
  handleFieldGetData = (e, index) => {
    const { fieldDataSource } = this.state
    const fieldDataSourceCopy = cloneDeep(fieldDataSource)
    fieldDataSourceCopy[index].getData = e.target.checked
    fieldDataSourceCopy[index].paramOperator = 0 // 设置操作符为 =
    this.setState({
      fieldDataSource: fieldDataSourceCopy,
    }, () => {
      this.calcRequestParamsAndResponseParam()
    })
  }

  // 参数选择 - 设为返回参数 - checkbox选择
  handleFieldReturnData = (e, index) => {
    const { fieldDataSource } = this.state
    const fieldDataSourceCopy = cloneDeep(fieldDataSource)
    fieldDataSourceCopy[index].returnData = e.target.checked
    this.setState({
      fieldDataSource: fieldDataSourceCopy,
    }, () => {
      this.calcRequestParamsAndResponseParam()
    })
  }

  /*
 * 根据选择参数的列表计算入参和返回参数的列表，调用时机如下
 * 1. 数据表名称切换
 * 2. 选择参数table 设为请求参数，设为返回参数checkbox勾选
 */
  calcRequestParamsAndResponseParam = () => {
    const responseParams = []
    const requestParams = []
    const { fieldDataSource } = this.state

    // 遍历参数表格
    fieldDataSource.forEach((column) => {
      const reqIndex = this.state?.requestParams?.findIndex((item) => item?.bindColumnName === column?.fieldName)
      // 如果被勾选了，首先看右侧对应的列表是否已存在，
      // 如果存在，直接复用，否则从选择参数表格中复制一份过去
      if (column.getData) {
        if (reqIndex > -1) {
          requestParams.push(this.state?.requestParams[reqIndex])
        } else {
          requestParams.push({ ...column })
        }
      }
      const resIndex = this.state?.responseParams?.findIndex((item) => item.bindColumnName === column.fieldName)
      if (column.returnData) {
        if (resIndex > -1) {
          responseParams.push(this.state.responseParams[resIndex])
        } else {
          responseParams.push({ ...column })
        }
      }
    })
    // responseParams.map(item => item.paramName = item?.fieldName)
    // requestParams.map(item => item.paramName = item?.fieldName)
    const changeParamDataType = item => {
      item.paramName = item?.fieldName
      if (paramDataTypeArr.indexOf(item.paramDataType) === -1) {
        item.paramDataType = 'STRING'
      }
      return item
    }
    this.setState(
      {
        responseParams: responseParams.map(changeParamDataType).map(responseIdMap),
        requestParams: requestParams.map(changeParamDataType).map(requestIdMap),
      },
    )
  }

  // API测试
  apiTest = () => {
    const { requestParams, responseParams, pageable } = this.state
    // return null
    this.dataSourceForm.current.validateFields().then(
      values => {
        this.testModalRef?.current?.toggleModal(values, requestParams, responseParams, pageable)
      },
    )
  }

  save = () => {
    const { requestParams, responseParams, pageable } = this.state
    this.dataSourceForm.current.validateFields().then((values) => {
      const { isSecurity, ...others } = values
      const requestParamsDataCopy = cloneDeep(requestParams) || []
      const responseParamsDataCopy = cloneDeep(responseParams)

      const params = this.descId ? { id: this.descId } : {}

      requestParamsDataCopy.map(item => { item.paramType = 0 })
      responseParamsDataCopy.map(item => { item.paramType = 1 })

      this.props.dispatch({
        type: 'indexApiCreate/querySaveIndexApi',
        params: {
          ...others,
          ...params,
          apiType: 3, // 写死
          inputParamRequest: requestParamsDataCopy,
          outputParamRequest: responseParamsDataCopy,
          pageable,
          isSecurity: isSecurity ? 1 : 0,
        },
        cb: (res) => {
          const { msg, status } = res || {}
          if (status === 200) {
            history.push('/data-service/api-manage/my-api')
            message.success('操作成功')
          } else {
            message.error(msg || '服务端错误')
          }
        },
      })
    })
  }

  handleTreeSelect = (value) => {
    this.setState({
      indexNameList: [],
      requestParams: [],
      responseParams: [],
      fieldDataSource: [],
    })
    this.dataSourceForm.current?.resetFields(['tableName', 'indexId'])

    value !== undefined && value !== null && this.queryGetPublishedIndex(value)
  }

  // 根据 选中的指标目录id查询指标、关联数据表
  queryGetPublishedIndex = (value, indexId) => {
    this.props.dispatch({
      type: 'indexApiCreate/queryGetPublishedIndex',
      params: {
        catalogId: value,
      },
      cb: (res) => {
        this.setState({
          indexNameList: res || [],
        }, () => {
          // 查详情的时候调用
          if (this.descId && res && res.length && indexId) {
            const tableNameArr = res?.filter(item => item?.indexId === indexId) || []
            const [first] = tableNameArr
            if (!first) return
            const { tblName, dsId } = first
            this.queryGetTableFieldList(dsId, tblName)
          } else if (!res.length) {
            message.warn('已发布的指标数据表数量为0，请检查各项指标数据的数据表！')
          }
        })
      },
    })
  }

  handleSelectIndexName = (value) => {
    const { indexNameList } = this.state
    const tableNameArr = indexNameList?.filter(item => item?.indexId === value) || []
    const tableName = tableNameArr[0]?.tblName
    const dsId = tableNameArr[0]?.dsId
    this.dataSourceForm.current?.setFieldsValue({ tableName })

    this.setState({
      fieldLoading: true,
      requestParams: [],
      responseParams: [],
      fieldDataSource: [],
    })
    this.queryGetTableFieldList(dsId, tableName)
  }

  // 根据选中的指标名称，查询参数选择列表
  queryGetTableFieldList = (dsId, tableName) => {
    this.props.dispatch({
      type: 'indexApiCreate/queryGetTableFieldList',
      params: {
        dsId,
        tableName,
      },
      cb: (res) => {
        const { data, msg, status } = res
        if (status === 200) {
          const fieldDataSourceTemp = data
          if (this.descId) {
            // 根据入参和返回参数列表，设置选择参数表格的勾选状态
            fieldDataSourceTemp?.forEach((fieldItem) => {
              // 默认名称为字段名，默认操作符为等于，默认必填
              fieldItem.paramName = fieldItem.bindColumnName
              fieldItem.paramOperator = 0
              // fieldItem.paramRequire = 1

              this.state.requestParams.forEach((requestParam) => {
                if (requestParam.bindColumnName === fieldItem.bindColumnName) {
                  fieldItem.getData = true
                }
              })

              this.state.responseParams.forEach((responseParam) => {
                if (responseParam.bindColumnName === fieldItem.bindColumnName) {
                  fieldItem.returnData = true
                }
              })
            })
          }
          this.setState({
            fieldDataSource: fieldDataSourceTemp,
            fieldLoading: false,
          })
        } else {
          message.error(msg || '服务端错误')
          this.setState({
            fieldLoading: false,
          })
        }
      },
    })
  }

  render() {
    const {
      fieldDataSource, fieldLoading, requestParams, responseParams, apiGroupList, pageable, treeData, indexNameList,
    } = this.state
    const param_columns = [
      {
        title: (
          <div>
            <Checkbox
              checked={
                fieldDataSource?.length > 0
                && !fieldDataSource?.some((item) => !item.getData)
              }
              indeterminate={
                fieldDataSource?.some((item) => item.getData)
                && fieldDataSource?.some((item) => !item.getData)
              }
              disabled={fieldDataSource?.length === 0}
              onChange={(e) => {
                const fieldDataSourceCopy = cloneDeep(fieldDataSource)
                fieldDataSourceCopy.map(item => {
                  item.getData = e.target.checked
                  item.paramOperator = 0 // 设置操作符为 =
                  return null
                })
                this.setState({
                  fieldDataSource: fieldDataSourceCopy,
                }, () => {
                  this.calcRequestParamsAndResponseParam()
                })
              }}
            />
            <span className={styles.column_title}>设为请求参数</span>
          </div>
        ),
        dataIndex: 'getData',
        width: '20%',
        render: (text, record, index) => (
          <Checkbox
            checked={text}
            onChange={(e) => {
              this.handleFieldGetData(e, index)
              // this.calcRequestParamsAndResponseParams()
            }}
          />
        ),
      },
      {
        title: (
          <div>
            <Checkbox
              checked={
                fieldDataSource.length > 0
                && !fieldDataSource.some((item) => !item.returnData)
              }
              indeterminate={
                fieldDataSource.some((item) => item.returnData)
                && fieldDataSource.some((item) => !item.returnData)
              }
              disabled={fieldDataSource.length === 0}
              onChange={(e) => {
                const fieldDataSourceCopy = cloneDeep(fieldDataSource)
                fieldDataSourceCopy.map(item => {
                  item.returnData = e.target.checked
                  return null
                })
                this.setState({
                  fieldDataSource: fieldDataSourceCopy,
                }, () => {
                  this.calcRequestParamsAndResponseParam()
                })
              }}
            />
            <span className={styles.column_title}>设为返回参数</span>
          </div>
        ),
        dataIndex: 'returnData',
        width: '20%',
        render: (text, record, index) => (
          <Checkbox
            checked={text}
            // disabled={!this.state.writeAuth}
            onChange={(e) => {
              this.handleFieldReturnData(e, index)
            }}
          />
        ),
      },
      {
        title: '字段名',
        dataIndex: 'fieldName',
        width: '18%',
        ellipsis: true,
      },
      {
        title: '字段类型',
        dataIndex: 'fieldType',
        width: '18%',
        ellipsis: true,
      },
      {
        title: '字段描述',
        dataIndex: 'comment',
        width: '24%',
        ellipsis: true,
        render: (comment) => (comment || '-'),
      },
    ]

    return (
      <div className={styles.my_api_create}>
        <BreadcrumbBar menu={menuList} />
        <div className={styles.back_bar}>
          <i
            className="iconfont icon-zuo"
            onClick={() => { history.push('/data-service/api-manage/my-api') }}
            style={{ cursor: 'pointer' }}
          />
          <span onClick={() => { history.push('/data-service/api-manage/my-api') }}>指标API</span>
        </div>
        <div className={styles.container}>
          <Form
            ref={this.dataSourceForm}
            labelCol={{ span: 3 }}
            wrapperCol={{ span: 10 }}
            autoComplete="off"
          >
            <Item>
              <div className={styles.column}>基础设置</div>
            </Item>
            <Item
              label="API名称"
              name="apiName"
              rules={[
                { required: true, message: '请输入API名称' },
                {
                  pattern: new RegExp(descRe.reg, 'g'),
                  message: descRe.text,
                }]}
            >
              <Input placeholder="请输入API名称" />
            </Item>
            <Item
              label="API Path"
              name="apiPath"
              rules={[
                { required: true, message: '请输入API Path' },
                {
                  pattern: new RegExp(txtRe.reg, 'g'),
                  message: txtRe.text,
                },
                {
                  pattern: new RegExp(pathRe.reg, 'g'),
                  message: pathRe.text,
                },
              ]}
            >
              <Input placeholder="请输入API Path" />
            </Item>
            <Item
              label="API协议"
              name="apiProtocol"
              rules={[{ required: true, message: '请选择API协议' }]}
              initialValue="0"
            >
              <Radio.Group>
                <Radio value="0">HTTP</Radio>
                {/* <Radio value="1">HTTPS</Radio> */}
              </Radio.Group>
            </Item>
            <Item
              label="请求方式"
              name="apiMethod"
              rules={[{ required: true, message: '请选择API协议' }]}
              initialValue="GET"
            >
              <Radio.Group>
                <Radio value="GET">GET</Radio>
                <Radio value="POST">POST</Radio>
              </Radio.Group>
            </Item>
            <Item
              label="认证方式"
              name="authType"
              rules={[{ required: true, message: '请选择authType' }]}
              initialValue={0}
            >
              <Radio.Group>
                <Radio value={0}>ApiToken认证</Radio>
                <Radio value={1}>UserToken认证</Radio>
              </Radio.Group>
            </Item>
            <Item
              label="API分组"
              name="apiGroupId"
              rules={[
                { required: true, message: '请选择API分组' },
              ]}
            >
              <TreeSelect
                allowClear
                showSearch
                getPopupContainer={(triggerNode) => triggerNode.parentNode}
                // dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                treeData={apiGroupList}
                placeholder="请输入选择目录"
                treeDefaultExpandAll
                filterTreeNode={(input, treeNode) => treeNode?.dirName.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                fieldNames={{
                  label: 'dirName', value: 'id', children: 'children',
                }}
              />
            </Item>
            <Item
              label="出入参是否加密"
              name="isSecurity"
              initialValue={0}
              valuePropName="checked"
            >
              <Switch />
            </Item>
            <Item
              label="描述"
              name="apiDesc"
              rules={[
                {
                  pattern: new RegExp(lenRe.reg, 'g'),
                  message: lenRe.text,
                },
              ]}
            >
              <TextArea rows={2} />
            </Item>
            <Item>
              <div className={styles.column}>数据配置</div>
            </Item>
            <Item
              label="指标目录"
              name="dirId"
              rules={[
                { required: true, message: '请选择指标目录' },
              ]}
            >
              <TreeSelect
                allowClear
                showSearch
                getPopupContainer={(triggerNode) => triggerNode.parentNode}
                treeData={treeData}
                placeholder="请输入选择目录"
                treeDefaultExpandAll
                filterTreeNode={(input, treeNode) => treeNode?.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                fieldNames={{
                  label: 'name', value: 'id', children: 'children',
                }}
                onChange={this.handleTreeSelect}
              />
            </Item>
            <Item
              label="指标名称"
              name="indexId"
              rules={[
                { required: true, message: '请选择指标名称' },
              ]}
            >
              <Select
                allowClear
                showSearch
                placeholder="请选择指标名称"
                filterOption={(input, option) => option.props?.children
                  ?.toLowerCase()
                  ?.indexOf(input?.toLowerCase()) >= 0}
                onChange={this.handleSelectIndexName}
              >
                {
                  indexNameList?.map(item => (
                    // <Option key={item?.dsId}>{item?.name}</Option>
                    <Option key={item?.indexId} value={item?.indexId}>{item?.name}</Option>
                  ))
                }
              </Select>
            </Item>
            <Item
              label="关联数据表"
              name="tableName"
              rules={[
                // { required: true, message: '请选择指标名称' },
              ]}
            >
              <Input disabled={indexNameList.length === 0} placeholder="请输入关联数据表" />
            </Item>
            <Item
              label="参数选择"
              labelCol={{ span: 3 }}
              wrapperCol={{ span: 21 }}
              className={styles.sign}
            >
              <ProTable
                loading={fieldLoading}
                rowKey="fieldName"
                columns={param_columns}
                dataSource={fieldDataSource}
                pagination={null}
              />
            </Item>
            <Item
              label="请求参数设置"
              labelCol={{ span: 3 }}
              wrapperCol={{ span: 21 }}
              className={styles.sign}
            >
              <ProTable
                ref={this.reqTableRef}
                rowKey="id"
                columns={this.selectedApiTypeToColumn('request')}
                dataSource={requestParams}
                pagination={null}
                className="table-footer-no-padding"
                scroll={requestParams?.length > 6 ? { x: true, y: 320 } : null}
              // components={{
              //   header: {
              //     wrapper: proTableHeaderWrapperAddButton(this.addNewParamsRow('request'), 'requestAddTr', '添加请求参数'),
              //   },
              // }}
              />
            </Item>
            <Item
              label="返回参数设置"
              labelCol={{ span: 3 }}
              wrapperCol={{ span: 21 }}
              className={styles.sign}
            >
              <ProTable
                ref={this.resTableRef}
                rowKey="id"
                columns={this.selectedApiTypeToColumn()}
                className="table-footer-no-padding"
                pagination={null}
                dataSource={responseParams}
                scroll={responseParams?.length > 6 ? { x: true, y: 320 } : null}
              // components={{
              //   header: {
              //     wrapper: proTableHeaderWrapperAddButton(this.addNewParamsRow('response'), 'responseAddTr', '添加返回参数'),
              //   },
              // }}
              />
            </Item>
            <Item
              label=" "
              colon={false}
              labelCol={{ span: 3 }}
              wrapperCol={{ span: 21 }}
            >
              <Checkbox
                checked={pageable === 1}
                onChange={(e) => {
                  this.setState(
                    {
                      pageable: e.target.checked ? 1 : 0,
                    },
                  )
                }}
              >
                返回结果分页
              </Checkbox>
            </Item>
          </Form>
        </div>
        <div className={styles.edit_footer}>
          <Button
            className={styles.edit_btn}
            onClick={() => { history.push('/data-service/api-manage/my-api') }}
          >
            取消
          </Button>
          <Button
            className={styles.edit_btn}
            type="primary"
            onClick={this.apiTest}
          >
            API测试
          </Button>
          <Button
            className={styles.edit_btn}
            type="primary"
            onClick={this.save}
          >
            确定
          </Button>
        </div>
        <TestModal ref={this.testModalRef} />
      </div>
    )
  }
}

export default ProduceApiCreate
